<template
  ><div>
    <n-grid cols="4">
      <n-grid-item span="1"
        ><n-card title="在线节点"
          ><n-data-table
            :columns="nodeTableColumns"
            :data="nodeTableData"
            :row-key="rowKey"
            @update-checked-row-keys="handleCheckNodeTable" /></n-card
      ></n-grid-item>
      <n-grid-item span="2"><div ref="chartRef" :style="{ height, width }"></div></n-grid-item>
      <n-grid-item span="1"
        ><n-card title="链路质量表"
          ><n-data-table :columns="linkColumns" :data="linkData" :scroll-x="400" /></n-card
      ></n-grid-item>
    </n-grid> </div
></template>
<script lang="ts" setup>
  import type { DataTableColumns, DataTableRowKey } from 'naive-ui';
  import { getStatusConfig } from '@/api/status';
  import { computed, onBeforeUnmount, onMounted, ref, Ref, toRaw } from 'vue';
  import type { NodeInfo } from '@/api/status';
  import { useECharts } from '@/hooks/web/useECharts';
  import { basicProps } from './props';

  interface RowData {
    key: number;
    id: number;
    node: string;
  }

  // 定时器引用
  const refreshTimer = ref<number | null>(null);
  // 刷新间隔
  const refreshInterval = 5000; // 5秒刷新一次

  const nodeInfos = ref<NodeInfo[]>([]);
  const nodeTableData = computed(() => {
    return nodeInfos.value.map((nodeInfo) => ({
      id: nodeInfo.id,
      node: `${nodeInfo.ip}[${(nodeInfo.resourceRatio * 100).toFixed(1)}%]`,
    }));
  });
  const rowKey = (row: RowData) => row.id;
  const checkNodeRowKeysRef = ref<DataTableRowKey[]>([]);
  function handleCheckNodeTable(rowKeys: DataTableRowKey[]) {
    checkNodeRowKeysRef.value = rowKeys;
    // console.log(checkNodeRowKeysRef.value);
    const checkNodeInfos = toRaw(nodeInfos.value).filter((node) =>
      checkNodeRowKeysRef.value.includes(node.id)
    );
    // console.log(checkNodeInfos);
    updateTopologyCharts([...checkNodeInfos]);
  }
  const nodeTableColumns: DataTableColumns<RowData> = [
    { type: 'selection' },
    { title: '节点id', key: 'id' },
    {
      title: '在线节点',
      key: 'node',
    },
  ];

  /********************************拓扑图*************************************/
  defineProps({
    ...basicProps,
  });
  const chartRef = ref<HTMLDivElement | null>(null);
  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);

  const center = { x: 400, y: 400 }; // 圆心坐标
  const radius = 200; // 圆心半径

  //在圆周上动态生成节点坐标
  const generateCircularNodes = (count: number, nodeInfos: NodeInfo[]) => {
    return Array.from({ length: count }, (_, i) => {
      const angle = (2 * Math.PI * i) / count;
      return {
        name: nodeInfos[i].id.toString(),
        x: center.x + radius * Math.cos(angle),
        y: center.y + radius * Math.sin(angle),
        label: {
          show: true,
        },
        tooltip: {
          formatter: (value) => {
            return `ID:${value.name} IP:${nodeInfos[i].ip}`;
          },
        },
      };
    });
  };
  const generateAllLinks = (nodes: Array<{ name: string }>) => {
    const links = [] as Array<{
      source: string;
      target: string;
      lineStyle: { curveness: number; color: string };
      label: { show: boolean; formatter: () => string };
    }>;
    for (let i = 0; i < nodes.length; i++) {
      const linkMap = nodeLinkQuality.get(Number(nodes[i].name));
      const linkArr = nodes.map((item) => linkMap?.get(Number(item.name)));
      //   console.log(linkArr);
      for (let j = 0; j < nodes.length; j++) {
        if (i === j) {
          continue;
        }

        const quality = linkArr[j];
        let color = quality === undefined ? 'red' : quality <= -10 ? 'red' : 'green';

        links.push({
          source: nodes[i].name,
          target: nodes[j].name,
          lineStyle: {
            curveness: 0.1,
            color: color,
          },
          label: {
            show: true,
            formatter: () => {
              return quality === undefined ? '' : quality?.toString();
            },
          },
        });
      }
    }
    return links;
  };

  function updateTopologyCharts(nodeinfos: NodeInfo[]) {
    // console.log(nodeinfos);
    const nodes =
      !nodeinfos || nodeinfos.length === 0
        ? []
        : [...generateCircularNodes(nodeinfos.length, nodeinfos)];
    const links = generateAllLinks(nodes);
    setOptions({
      title: {
        text: '拓扑图',
      },
      tooltip: {},
      series: [
        {
          type: 'graph',
          layout: 'none',
          symbolSize: 50,
          roam: true,
          label: {
            show: true,
          },
          edgeSymbol: ['circle', 'arrow'],
          edgeSymbolSize: [4, 10],
          edgeLabel: {
            fontSize: 20,
          },
          data: nodes,
          links: links,
        },
      ],
    });
  }

  /*****************************************链路质量表******************************************/
  const linkQuality = ref<number[][]>([]);
  const nodeLinkQuality: Map<number, Map<Number, number>> = new Map();
  const linkColumns = ref<any[]>([]);
  const linkData = ref<any[]>([]);

  function updateLinkQuality() {
    if (
      nodeInfos.value.length === 0 ||
      linkQuality.value.length === 0 ||
      linkQuality.value.length === 1
    ) {
      return;
    }
    // console.log(linkQuality.value);
    const sortNodeId = nodeInfos.value.map((nodeinfo) => nodeinfo.id).sort((a, b) => a - b);
    for (let i = 0; i < sortNodeId.length; ++i) {
      const rowNodeLinks: Map<number, number> = new Map();
      for (let j = 0; j < sortNodeId.length; ++j) {
        rowNodeLinks.set(sortNodeId[j], linkQuality.value[i][j]);
      }
      nodeLinkQuality.set(sortNodeId[i], rowNodeLinks);
    }
    // console.log(nodeLinkQuality);
    const firstCol = { title: '节点', key: 'id', fixed: 'left' };
    const otherCols = sortNodeId.map((id) => ({ title: id.toString(), key: id, fixed: false }));
    linkColumns.value = [firstCol, ...otherCols];
    linkData.value = sortNodeId.map((value) => {
      const rowData = { id: value };
      sortNodeId.forEach((val) => {
        rowData[val] =
          nodeLinkQuality.get(value)?.get(val) === -10
            ? null
            : nodeLinkQuality.get(value)?.get(val);
      });
      return rowData;
    });
    // console.log(linkData.value);
  }

  // 初始化定时器
  function initRefreshTimer() {
    // 立即更新一次
    updateNodeInfo();
    updateLinkQuality();

    refreshTimer.value = window.setInterval(() => {
      //   console.log('111');
      updateNodeInfo();
      updateLinkQuality();
    }, refreshInterval);
  }
  // 清除定时器
  function clearRefreshTimer() {
    if (refreshTimer.value) {
      clearInterval(refreshTimer.value);
      refreshTimer.value = null;
    }
  }
  // 更新数据
  async function updateNodeInfo() {
    const statusconfig = await getStatusConfig();
    nodeInfos.value = [...statusconfig.nodeInfos];
    linkQuality.value = [...statusconfig.linkQuality];
  }

  onMounted(async () => {
    // 初始化定时器
    initRefreshTimer();
  });

  onBeforeUnmount(() => {
    clearRefreshTimer();
  });
</script>
